/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.webservicecomponent.dt.core.refer;

import com.inspur.edp.cdp.cdf.component.manager.reference.ComponentReferenceManager;
import com.inspur.edp.component.schema.IGspCompResource;
import com.inspur.edp.component.schema.RefStructureInfo;
import com.inspur.edp.component.schema.resource.IApiResource;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataReference;
import com.inspur.edp.lcm.metadata.api.entity.uri.MetadataURI;
import com.inspur.edp.lcm.metadata.api.exception.MetadataNotFoundException;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import com.inspur.edp.webservicecomponent.metadata.WebServiceComponent;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 功能描述:
 *
 * @ClassName: RefConstraint
 * @Author: Fynn Qi
 * @Date: 2021/1/4 11:04
 * @Version: V1.0
 */
public class RefConstraint extends ComponentReferenceManager {

    private static final String IAPI_METADATA_TYPE = "InternalApi";

    /**
     * 业务资源为“内部服务元数据”时，将iapi元数据设置到refs中
     */
    @Override
    public List<MetadataReference> getReference(GspMetadata metadata) {
        if (metadata == null || metadata.getContent() == null) {
            return null;
        }
        WebServiceComponent wsComp = (WebServiceComponent) metadata.getContent();
        IGspCompResource resource = wsComp.getResource();
        if (resource == null || !IApiResource.KIND.equals(wsComp.getResource().getKind())) {
            return null;
        }
        IApiResource iApiResource = (IApiResource) resource;
        List<MetadataReference> metadataRefs = new ArrayList<>();
        this.setResourceReference(iApiResource, metadata, metadataRefs);
        return metadataRefs;
    }

    /**
     * 获取业务资源元数据依赖
     */
    private void setResourceReference(IApiResource iApiResource, GspMetadata metadata, List<MetadataReference> metadataRefs) {

        MetadataURI targetMdURI = new MetadataURI();
        targetMdURI.setId(iApiResource.getApiId());
        targetMdURI.setCode(iApiResource.getApiCode());
        targetMdURI.setType(IAPI_METADATA_TYPE);

        MetadataURI sourceMdURI = new MetadataURI();
        sourceMdURI.setId(metadata.getHeader().getId());
        sourceMdURI.setCode(metadata.getHeader().getCode());
        sourceMdURI.setType(metadata.getHeader().getType());
        sourceMdURI.setNameSpace(metadata.getHeader().getNameSpace());
        GspMetadata refMd;
        try {
            refMd = this.getRefMetadata(targetMdURI, sourceMdURI, metadata.getRelativePath());
        } catch (MetadataNotFoundException e) {
            String errMsg = MessageFormat.format("在加载业务资源【{0}】【code：{1}】时报错，找不到该内部服务元数据【ID：{2}】，请检查是否已删除",
                    iApiResource.getApiName(), targetMdURI.getCode(), targetMdURI.getId());
            throw new ReferenceMetadataNotFoundException(errMsg, e);
        }
        MetadataReference reference = new MetadataReference();
        reference.setMetadata(metadata.getHeader());
        reference.setDependentMetadata(refMd.getHeader());
        metadataRefs.add(reference);
    }

    private GspMetadata getRefMetadata(MetadataURI targetMdURI, MetadataURI sourceMdURI, String projectPath) {
        GspMetadata resourceMeta = SpringBeanUtils.getBean(RefCommonService.class)
                .getRefMetadata(targetMdURI, sourceMdURI, projectPath);
        return resourceMeta;
    }
}
